package com.eapi.project.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.eapi.eapicommom.model.entity.User;
import com.eapi.project.common.BaseResponse;
import com.eapi.project.common.ErrorCode;
import com.eapi.project.common.ResultUtils;
import com.eapi.project.constant.SystemConstants;
import com.eapi.project.exception.BusinessException;
import com.eapi.project.mapper.ArticleMapper;
import com.eapi.project.model.dto.article.AddArticleDto;
import com.eapi.project.model.dto.article.ArticleDeleteRequest;
import com.eapi.project.model.dto.article.ArticleTopRequest;
import com.eapi.project.model.dto.article.ArticleUpdateRequest;
import com.eapi.project.model.entity.Article;
import com.eapi.project.model.entity.Category;
import com.eapi.project.model.vo.*;
import com.eapi.project.service.ArticleService;
import com.eapi.project.service.CategoryService;
import com.eapi.project.service.UserService;
import com.eapi.project.utils.BeanCopyUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.util.Collections;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

@Service
public class ArticleServiceImpl extends ServiceImpl<ArticleMapper, Article> implements ArticleService {

    @Autowired
    CategoryService categoryService;

    @Resource
    UserService userService;

    @Override
    public BaseResponse<List<HotArticleVo>> hotArticleList() {
        //查询热门文章 封装成ResponseResult返回
        LambdaQueryWrapper<Article> queryWrapper = new LambdaQueryWrapper<>();
        //必须是正式文章
        queryWrapper.eq(Article::getStatus, SystemConstants.ARTICLE_STATUS_NORMAL);
        //按照浏览量进行排序
        queryWrapper.orderByDesc(Article::getViewCount);
        //最多只查询10条
        Page<Article> page = new Page(1, 10);
        page(page, queryWrapper);
        List<Article> articles = page.getRecords();
        List<HotArticleVo> vs = BeanCopyUtils.copyBeanList(articles, HotArticleVo.class);
        return ResultUtils.success(vs);
    }

    @Override
    public BaseResponse<PageVo> articleList(Integer pageNum, Integer pageSize, Long categoryId) {
        //查询条件
        LambdaQueryWrapper<Article> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        // 如果 有categoryId 就要 查询时要和传入的相同
        lambdaQueryWrapper.eq(Objects.nonNull(categoryId) && categoryId > 0, Article::getCategoryId, categoryId);
        // 状态是正式发布的
        lambdaQueryWrapper.eq(Article::getStatus, SystemConstants.ARTICLE_STATUS_NORMAL);
        // 对isTop进行降序
        lambdaQueryWrapper.orderByDesc(Article::getIsTop);
        lambdaQueryWrapper.orderByDesc(Article::getUpdateTime);
        //分页查询
        Page<Article> page = new Page<>(pageNum, pageSize);
        page(page, lambdaQueryWrapper);
        List<Article> articles = page.getRecords();
        //查询categoryName
        articles.stream()
                .map(article -> article.setCategoryName(categoryService.getById(article.getCategoryId()).getName()))
                .collect(Collectors.toList());

        //封装查询结果
        List<ArticleListVo> articleListVos = BeanCopyUtils.copyBeanList(page.getRecords(), ArticleListVo.class);
        PageVo pageVo = new PageVo(articleListVos, page.getTotal());
        return ResultUtils.success(pageVo);
    }


    @Override
    public BaseResponse<ArticleDetailVo> getArticleDetail(Long id) {
        //根据id查询文章
        Article article = getById(id);
        //转换成VO
        ArticleDetailVo articleDetailVo = BeanCopyUtils.copyBean(article, ArticleDetailVo.class);
        //根据分类id查询分类名
        Long categoryId = articleDetailVo.getCategoryId();
        Category category = categoryService.getById(categoryId);
        if (category != null) {
            articleDetailVo.setCategoryName(category.getName());
        }
        User writer = userService.getById(articleDetailVo.getCreateBy());
        String userName = writer.getUserName();
        articleDetailVo.setWriterName(userName == null || userName == ""? writer.getUserAccount() : userName);
        String userAvatar = writer.getUserAvatar();
        articleDetailVo.setWriterAvatar(userAvatar);
        String selfIntroduction = writer.getSelfIntroduction();
        articleDetailVo.setWriterIntro(selfIntroduction == null || selfIntroduction == ""? "这个人很懒，什么都没写" : selfIntroduction);
        // 更新文章的浏览量
        article.setViewCount(article.getViewCount() + 1);
        updateById(article);
        //封装响应返回
        return ResultUtils.success(articleDetailVo);
    }

    @Override
    public void addArticle(AddArticleDto addArticleDto, Long userId) {
        Article article = BeanCopyUtils.copyBean(addArticleDto, Article.class);
        article.setCreateBy(userId);
        article.setUpdateBy(userId);
        save(article);
    }


    @Override
    public BaseResponse<Boolean> deleteArticle(ArticleDeleteRequest deleteRequest, User user, HttpServletRequest request) {
        long id = deleteRequest.getId();
        // 判断是否存在
        Article oldArticle = getById(id);
        //校验权限
        boolean ownCondition = !oldArticle.getCreateBy().equals(user.getId());
        boolean adminCondition = !user.getUserRole().equals("admin");
        // 仅本人或管理员可删除
        if (ownCondition && adminCondition) {
            throw new BusinessException(ErrorCode.NO_AUTH_ERROR);
        }
        boolean b = removeById(id);
        return ResultUtils.success(b);
    }

    @Override
    public BaseResponse<Boolean> updateArticle(ArticleUpdateRequest articleUpdateRequest, User user) {
        Long articleId = articleUpdateRequest.getId();
        if (articleUpdateRequest == null || articleId <= 0) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR);
        }
        Article oldArticle = getById(articleId);
        Article article = new Article();
        BeanUtils.copyProperties(articleUpdateRequest, article);
        // 仅本人可修改
        if (!oldArticle.getCreateBy().equals(user.getId())) {
            throw new BusinessException(ErrorCode.NO_AUTH_ERROR,"仅仅允许本人修改");
        }
        article.setUpdateBy(user.getId());
        article.setCreateBy(oldArticle.getCreateBy());
        article.setIsTop(oldArticle.getIsTop());
        article.setViewCount(oldArticle.getViewCount());
        boolean result = updateById(article);
        return ResultUtils.success(result);
    }

    @Override
    public BaseResponse<PageVo> listAllArticle(Integer pageNum, Integer pageSize, User user) {
        if(!user.getUserRole().equals("admin")) throw new BusinessException(ErrorCode.NO_AUTH_ERROR);
        Page<Article> page = new Page<>(pageNum, pageSize);
        LambdaQueryWrapper<Article> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.orderByDesc(Article::getIsTop);
        queryWrapper.orderByDesc(Article::getUpdateTime);
        page(page,queryWrapper);
        List<Article> articles = page.getRecords();
        List<Article> allArtiles = articles.stream()
                .map(article -> article.setCategoryName(categoryService.getById(article.getCategoryId()).getName()))
                .collect(Collectors.toList());
        List<ListAllArticleVo> allArtileVos = BeanCopyUtils.copyBeanList(allArtiles, ListAllArticleVo.class);
        PageVo pageVo = new PageVo(allArtileVos, page.getTotal());
        return ResultUtils.success(pageVo);
    }

    @Override
    public BaseResponse<String> topArticle(ArticleTopRequest articleTopRequest, User user) {
        if(!user.getUserRole().equals("admin")) throw new BusinessException(ErrorCode.NO_AUTH_ERROR);
        Article article = getById(articleTopRequest.getId());
        article.setIsTop("1");
        article.setUpdateTime(article.getUpdateTime());
        updateById(article);
        return ResultUtils.success("置顶成功");
    }

    @Override
    public BaseResponse<String> cancelTopArticle(ArticleTopRequest articleTopRequest, User user) {
        if(!user.getUserRole().equals("admin")) throw new BusinessException(ErrorCode.NO_AUTH_ERROR);
        Article article = getById(articleTopRequest.getId());
        article.setIsTop("0");
        article.setUpdateTime(article.getUpdateTime());
        updateById(article);
        return ResultUtils.success("已取消置顶");
    }

    @Override
    public BaseResponse<PageVo> getDraft(User user, Integer pageNum, Integer pageSize) {
        LambdaQueryWrapper<Article> queryWrapper = new LambdaQueryWrapper<>();
        // 获取制定用户的文章
        queryWrapper.eq(Article::getCreateBy, user.getId());
        queryWrapper.eq(Article::getStatus, "1");
        // 按照常见时间排序
        queryWrapper.orderByDesc(Article::getCreateTime);
        // 分页查询
        Page page = new Page(pageNum, pageSize);
        Page<Article> articles = page(page, queryWrapper);
        // 设置分类名称
        List<Article> drafts = articles.getRecords().stream()
                .map(article -> article.setCategoryName(categoryService.getById(article.getCategoryId()).getName()))
                .collect(Collectors.toList());
        List<OwnArticleDraftsVo> ownDraftVos = BeanCopyUtils.copyBeanList(drafts, OwnArticleDraftsVo.class);
        PageVo pageVo = new PageVo(ownDraftVos, page.getTotal());
        return ResultUtils.success(pageVo);
    }

    @Override
    public BaseResponse<PageVo> getPublic(User user, Integer pageNum, Integer pageSize) {
        LambdaQueryWrapper<Article> queryWrapper = new LambdaQueryWrapper<>();
        // 获取制定用户的文章
        queryWrapper.eq(Article::getCreateBy, user.getId());
        queryWrapper.eq(Article::getStatus, "0");
        // 按照常见时间排序
        queryWrapper.orderByDesc(Article::getCreateTime);
        // 分页查询
        Page page = new Page(pageNum, pageSize);
        Page<Article> articles = page(page, queryWrapper);
        // 设置分类名称
        List<Article> drafts = articles.getRecords().stream()
                .map(article -> article.setCategoryName(categoryService.getById(article.getCategoryId()).getName()))
                .collect(Collectors.toList());
        List<OwnArticleDraftsVo> ownDraftVos = BeanCopyUtils.copyBeanList(drafts, OwnArticleDraftsVo.class);
        PageVo pageVo = new PageVo(ownDraftVos, page.getTotal());
        return ResultUtils.success(pageVo);
    }

}